home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / triq / 4d / 4d.c next >
Encoding:
C/C++ Source or Header  |  1992-09-12  |  11.3 KB  |  580 lines

  1. #include "windows.h"
  2. #include "4d.h"
  3.  
  4. /*
  5.      (C) Copyright Microsoft Corp. 1991.  All rights reserved.
  6.  
  7.      You have a royalty-free right to use, modify, reproduce and 
  8.      distribute the Sample Files (and/or any modified version) in 
  9.      any way you find useful, provided that you agree that 
  10.      Microsoft has no warranty obligations or liability for any 
  11.      Sample Application Files which are modified. 
  12.  */
  13.  
  14. extern int atoi(char *);
  15.  
  16. #define X 0
  17. #define Y 1
  18. #define Z 2
  19. #define W 3
  20.  
  21.  
  22. MATRIXFX Matrix4D (FIXED4D m11,FIXED4D m12,FIXED4D m13,FIXED4D m14,
  23.            FIXED4D m21,FIXED4D m22,FIXED4D m23,FIXED4D m24,
  24.            FIXED4D m31,FIXED4D m32,FIXED4D m33,FIXED4D m34,
  25.            FIXED4D m41,FIXED4D m42,FIXED4D m43,FIXED4D m44);
  26.  
  27.  
  28. /* Exports */
  29. POINTFX4D  Origin  = {0,0,0,FX(1)};
  30. FIXED4D     epsilon = MAKEFX(0,1);   /* 0.0001; */
  31.  
  32. POINTFX4D CreatePoint4D(x,y,z,w)
  33. FIXED4D x,y,z,w;
  34. {
  35.   POINTFX4D NewPoint;
  36.   NewPoint.x = x;
  37.   NewPoint.y = y;
  38.   NewPoint.z = z;
  39.   NewPoint.w = w;
  40.   return NewPoint;
  41. }
  42.  
  43. MATRIXFX Matrix4D (FIXED4D m11,FIXED4D m12,FIXED4D m13,FIXED4D m14,
  44.            FIXED4D m21,FIXED4D m22,FIXED4D m23,FIXED4D m24,
  45.            FIXED4D m31,FIXED4D m32,FIXED4D m33,FIXED4D m34,
  46.            FIXED4D m41,FIXED4D m42,FIXED4D m43,FIXED4D m44)
  47.  
  48. {
  49.     MATRIXFX M;
  50.  
  51.     M.T[0][0] = m11; M.T[0][1] = m12; M.T[0][2] = m13; M.T[0][3] = m14;
  52.     M.T[1][0] = m21; M.T[1][1] = m22; M.T[1][2] = m23; M.T[1][3] = m24;
  53.     M.T[2][0] = m31; M.T[2][1] = m32; M.T[2][2] = m33; M.T[2][3] = m34;
  54.     M.T[3][0] = m41; M.T[3][1] = m42; M.T[3][2] = m43; M.T[3][3] = m44;
  55.  
  56.     return M;
  57. }
  58.  
  59.  
  60. /*
  61. **  Return the point 1 t-th along the way
  62. **  from P0 to P1.
  63. */
  64. extern POINTFX4D Ratio4D(P0,P1,t)
  65.     POINTFX4D P0,P1;
  66.     FIXED4D t;
  67. {
  68.     POINTFX4D P;
  69.  
  70.     P.x = P0.x + FXMUL(t,(P1.x - P0.x));
  71.     P.y = P0.y + FXMUL(t,(P1.y - P0.y));
  72.     P.z = P0.z + FXMUL(t,(P1.z - P0.z));
  73.     P.w = ONE;
  74.  
  75.     return P;
  76. }
  77.  
  78. POINTFX4D PxT4D(P,T)
  79.     POINTFX4D P;
  80.     MATRIXFX *T;
  81. {
  82.     POINTFX4D Q;
  83.     int     i,k;
  84.     FIXED4D   Qi;
  85.  
  86. #ifdef HOMO
  87.     for (i = 0; i < 4; i++)
  88.     {
  89.     Qi = ZERO;
  90.     for (k = 0; k < 4; k++)
  91.         Qi += FXMUL(P.P[k],(T->T[i][k]));
  92.     Q.P[i] = Qi;
  93.     }
  94. #else
  95.     Q.x = T->T[0][3] + FXMUL(P.x,T->T[0][0]) + FXMUL(P.y,T->T[0][1]) + FXMUL(P.z,T->T[0][2]);
  96.     Q.y = T->T[1][3] + FXMUL(P.x,T->T[1][0]) + FXMUL(P.y,T->T[1][1]) + FXMUL(P.z,T->T[1][2]);
  97.     Q.z = T->T[2][3] + FXMUL(P.x,T->T[2][0]) + FXMUL(P.y,T->T[2][1]) + FXMUL(P.z,T->T[2][2]);
  98. #endif
  99.     return Q;
  100. }
  101.  
  102. void TransformPoints(pT,pP,pD,cnt)
  103.     MATRIXFX     *pT;
  104.     POINTFX4D  FAR *pP;
  105.     POINTFX4D  FAR *pD;
  106.     int          cnt;
  107. {
  108.     FIXED4D x,y,z,w;
  109.  
  110.     while (cnt-- > 0)
  111.     {
  112.         x = pP->x;
  113.         y = pP->y;
  114.         z = pP->z;
  115.         w = pP->w;
  116.  
  117.         if (w == ZERO)
  118.         {
  119.             pD->x = FXMUL(x,pT->T[0][0]) + FXMUL(y,pT->T[0][1]) + FXMUL(z,pT->T[0][2]);
  120.             pD->y = FXMUL(x,pT->T[1][0]) + FXMUL(y,pT->T[1][1]) + FXMUL(z,pT->T[1][2]);
  121.             pD->z = FXMUL(x,pT->T[2][0]) + FXMUL(y,pT->T[2][1]) + FXMUL(z,pT->T[2][2]);
  122.             pD->w = w;
  123.         }
  124.         else
  125.         {
  126.             pD->x = pT->T[0][3] + FXMUL(x,pT->T[0][0]) + FXMUL(y,pT->T[0][1]) + FXMUL(z,pT->T[0][2]);
  127.             pD->y = pT->T[1][3] + FXMUL(x,pT->T[1][0]) + FXMUL(y,pT->T[1][1]) + FXMUL(z,pT->T[1][2]);
  128.             pD->z = pT->T[2][3] + FXMUL(x,pT->T[2][0]) + FXMUL(y,pT->T[2][1]) + FXMUL(z,pT->T[2][2]);
  129.             pD->w = w;
  130.         }
  131.  
  132.         pP++;
  133.         pD++;
  134.     }
  135. }
  136.  
  137.  
  138. MATRIXFX Transpose4D(T)
  139.     MATRIXFX *T;
  140. {
  141.     MATRIXFX Tt;
  142.     int i,j;
  143.  
  144.     for (i=0; i<4; i++) {
  145.     for (j=0; j<4; j++) {
  146.         Tt.T[i][j] = T->T[j][i];
  147.     }
  148.     }
  149.     return Tt;
  150. }
  151.  
  152. MATRIXFX TxT4D(A, B)
  153.     MATRIXFX *A, *B;
  154. {
  155.     MATRIXFX C;
  156.     int      i,j,k;
  157.     FIXED4D    Cij;
  158.  
  159.     for (j = 0; j < 4; j++)
  160.     for (i = 0; i < 4; i++)
  161.     {
  162.         Cij = ZERO;
  163.         for (k = 0; k < 4; k++)
  164.         Cij += FXMUL(A->T[k][j],B->T[i][k]);
  165.         C.T[i][j] = Cij;
  166.     }
  167.     return C;
  168. }
  169.  
  170. MATRIXFX Identity4D()
  171. {
  172.     MATRIXFX I;
  173.     int      i,j;
  174.  
  175.     for (i = 0; i < 4; i++)
  176.     for (j = 0; j < 4; j++)
  177.         I.T[i][j] = FX(i == j);
  178.     return I;
  179. }
  180.  
  181. MATRIXFX Translate4D(V)
  182.     VECTORFX V;
  183. {
  184.     MATRIXFX T;
  185.  
  186.     T = Identity4D();
  187.     T.T[0][3] = V.x;
  188.     T.T[1][3] = V.y;
  189.     T.T[2][3] = V.z;
  190.     return T;
  191. }
  192.  
  193. MATRIXFX UniformScale4D(s)
  194.     FIXED4D s;
  195. {
  196.     return Scale4D(CreatePoint4D(s,s,s,ONE));
  197. }
  198.  
  199. MATRIXFX Scale4D(P)
  200.     POINTFX4D P;
  201. {
  202.     MATRIXFX T;
  203.  
  204.     T = Identity4D();
  205.     T.T[0][0] = P.x;
  206.     T.T[1][1] = P.y;
  207.     T.T[2][2] = P.z;
  208.     T.T[3][3] = P.w;
  209.     return T;
  210. }
  211.  
  212. /******************************************************************************
  213.  returns a Matrix to rotate about the z axis
  214. ******************************************************************************/
  215. MATRIXFX RotateZ (deg)
  216.     FIXED4D deg;
  217. {
  218.     return Matrix4D( fxcos(deg),  -fxsin(deg),   ZERO, ZERO,
  219.                      fxsin(deg),   fxcos(deg),   ZERO, ZERO,
  220.                      ZERO,         ZERO,         ONE,  ZERO,
  221.                      ZERO,         ZERO,         ZERO, ONE);
  222. }
  223.  
  224.  
  225. /******************************************************************************
  226.  returns a Matrix to rotate about the y axis
  227. ******************************************************************************/
  228. MATRIXFX RotateY (deg)
  229.     FIXED4D deg;
  230. {
  231.      return Matrix4D( fxcos(deg),   ZERO,  -fxsin(deg),   ZERO,
  232.                       ZERO,         ONE,    ZERO,         ZERO,
  233.                       fxsin(deg),   ZERO,   fxcos(deg),   ZERO,
  234.                       ZERO,         ZERO,   ZERO,         ONE);
  235. }
  236.  
  237.  
  238. /******************************************************************************
  239.  returns a Matrix to rotate about the x axis
  240. ******************************************************************************/
  241. MATRIXFX RotateX (deg)
  242.     FIXED4D deg;
  243. {
  244.     return Matrix4D( ONE,        ZERO,          ZERO,         ZERO,
  245.                      ZERO,       fxcos(deg),   -fxsin(deg),   ZERO,
  246.                      ZERO,       fxsin(deg),    fxcos(deg),   ZERO,
  247.                      ZERO,       ZERO,          ZERO,         ONE);
  248. }
  249.  
  250. MATRIXFX Perspective4D(f)
  251.     FIXED4D f;
  252. {
  253.     MATRIXFX P;
  254.  
  255.     P = Identity4D();
  256.     if ((f < epsilon) && (f > (-epsilon)))
  257.     {
  258.     /* fprintf(stderr,"Perspective4D: f (%d.%d) is too small.\n",f); */
  259.     if (f < ZERO) f = (-epsilon);
  260.     else          f =   epsilon;
  261.     }
  262.     P.T[2][2] = FXDIV(ONE,f);     P.T[3][2] = FXDIV(ONE,f);
  263.     P.T[2][3] = -ONE;         P.T[3][3] = ZERO;
  264.     return P;
  265. }
  266. #if 0
  267. void PrintFx(fx)
  268.     FIXED4D fx;
  269. {
  270.     WORD    f;
  271.     int     i;
  272.  
  273.     if (fx < 0)
  274.     {
  275.     fx = -fx;
  276.         i  = -FXINT(fx);
  277.         f  = FXDFRAC(fx);
  278.     }
  279.     else
  280.     {
  281.         i  = FXINT(fx);
  282.         f  = FXDFRAC(fx);
  283.     }
  284.     WinPrintf("%5d.%04u ",i,f);
  285. }
  286. #endif
  287.  
  288. FIXED4D atofx(sz)
  289.     char *sz;
  290. {
  291.     int  i;
  292.     WORD f;
  293.     FIXED4D fx;
  294.     BOOL fminus = FALSE;
  295.     int  d;
  296.  
  297.     if (*sz == '-')
  298.       {
  299.        fminus = TRUE;
  300.        sz++;
  301.       }
  302.  
  303.     i = atoi(sz);
  304.  
  305.     while (*sz && *sz != '.')
  306.     sz++;
  307.  
  308.     if (*sz)
  309.     f = atoi(++sz);
  310.     else
  311.     f = 0;
  312.  
  313.     if (f < 10)
  314.     d = 10;
  315.     else if (f < 100)
  316.     d = 100;
  317.     else if (f < 1000)
  318.     d = 1000;
  319.     else if (f < 10000)
  320.     d = 10000;
  321.  
  322.     f = (WORD)((DWORD)f * 65536L / d);
  323.  
  324.     fx = MAKEFIXED4D(i,f);
  325.  
  326.     if (fminus)
  327.       {
  328.         fx = -fx;
  329.       }
  330.     return fx;
  331. }
  332.  
  333. #if 0
  334. void PrintMatrix(T)
  335.     MATRIXFX *T;
  336. {
  337.     int i,j;
  338.  
  339.     for (i=0; i<4; i++)
  340.     {
  341.     WinPrintf("|");
  342.     for (j=0; j<4; j++) {
  343.         WinPrintf(" ");
  344.         PrintFx(T->T[j][i]);
  345.         WinPrintf(" ");
  346.     }
  347.     WinPrintf("|\n");
  348.     }
  349. }
  350.  
  351. void PrintPoint(P)
  352.     POINTFX4D P;
  353. {
  354.     WinPrintf("(");
  355.     PrintFx(P.x); WinPrintf(" ");
  356.     PrintFx(P.y); WinPrintf(" ");
  357.     PrintFx(P.z); WinPrintf(" ");
  358.     PrintFx(P.w); WinPrintf(")");
  359. }
  360. #endif
  361.  
  362. /*
  363. ** Vectors are represented as 4-tuples with the last component
  364. ** being 0.  This representation allows them to be correctly transformed
  365. ** by homogeneous matrices.
  366. */
  367. VECTORFX CreateVector4D(a,b,c)
  368.     FIXED4D a,b,c;
  369. {
  370.     VECTORFX NewVector;
  371.  
  372.     NewVector.x = a;
  373.     NewVector.y = b;
  374.     NewVector.z = c;
  375.     NewVector.w = ZERO;
  376.     return NewVector;
  377. }
  378.  
  379. #if 0
  380. void PrintVector(V)
  381.     VECTORFX V;
  382. {
  383.     WinPrintf("[");
  384.     PrintFx(V.x); WinPrintf(" ");
  385.     PrintFx(V.y); WinPrintf(" ");
  386.     PrintFx(V.z); WinPrintf(" ");
  387.     PrintFx(V.w); WinPrintf("]");
  388. }
  389. #endif
  390.  
  391. VECTORFX VxT4D(V,T)
  392.     VECTORFX V;
  393.     MATRIXFX *T;
  394. {
  395.     VECTORFX Q;
  396.  
  397.     Q.x = FXMUL(V.x,T->T[0][0]) + FXMUL(V.y,T->T[0][1]) + FXMUL(V.z,T->T[0][2]);
  398.     Q.y = FXMUL(V.x,T->T[1][0]) + FXMUL(V.y,T->T[1][1]) + FXMUL(V.z,T->T[1][2]);
  399.     Q.z = FXMUL(V.x,T->T[2][0]) + FXMUL(V.y,T->T[2][1]) + FXMUL(V.z,T->T[2][2]);
  400.     return Q;
  401. }
  402.  
  403. VECTORFX Cross4D(v1, v2)
  404.     VECTORFX v1, v2;
  405. {
  406.     VECTORFX v;
  407.  
  408. #if 1
  409.     fxCross4D(&v,v1,v2);
  410. #else
  411.     v.x =   FXMUL(v1.y,v2.z) - FXMUL(v1.z,v2.y);
  412.     v.y = -(FXMUL(v1.x,v2.z) - FXMUL(v1.z,v2.x));
  413.     v.z =   FXMUL(v1.x,v2.y) - FXMUL(v1.y,v2.x);
  414.     v.w =   ZERO;
  415. #endif
  416.  
  417.     return v;
  418. }
  419.  
  420. FIXED4D Dot4D(v1,v2)
  421.     VECTORFX v1, v2;
  422. {
  423. #if 0
  424.     if (v1.x < 0)
  425.     v1.x  = - v1.x;
  426.     if (v1.y < 0)
  427.     v1.y  = - v1.y;
  428.     if (v1.z < 0)
  429.     v1.z  = - v1.z;
  430. #endif
  431.  
  432.     return FXMUL(v1.x,v2.x) + FXMUL(v1.y,v2.y) + FXMUL(v1.z,v2.z);
  433. }
  434.  
  435. FIXED4D Vmag( v)
  436.     VECTORFX v;
  437. {
  438.     return fxLength3D(v.x,v.y,v.z);
  439. }
  440.  
  441. ULONG ulVmag(v)
  442.     VECTORFX v;
  443. {
  444.     return ulsqrt((ULONG)lDot4D(v,v));
  445. }
  446.  
  447. VECTORFX Normalize(v)
  448.     VECTORFX v;
  449. {
  450.     VECTORFX vout;
  451.     FIXED4D l = Vmag(v);
  452.  
  453.     if (l == 0) {
  454.         return v;
  455.         /* printf("Can't normalize a zero vector.\n"); */
  456.         /* exit(-1); */
  457.     }
  458.  
  459.     vout.x = FXDIV(v.x,l);
  460.     vout.y = FXDIV(v.y,l);
  461.     vout.z = FXDIV(v.z,l);
  462.     vout.w = ZERO;
  463.  
  464.     return vout;
  465. }
  466.  
  467. /*
  468. ** Return the vector V=P1-P0.
  469. */
  470. extern VECTORFX Pdiff(P1,P0)
  471. POINTFX4D P1,P0;
  472. {
  473.     VECTORFX V;
  474.  
  475. #ifdef HOMO
  476.   P1.x /= P1.w; P1.y /= P1.w; P1.z /= P1.w;
  477.   P0.x /= P0.w; P0.y /= P0.w; P0.z /= P0.w;
  478. #endif
  479.  
  480.     V.x = P1.x - P0.x;
  481.     V.y = P1.y - P0.y;
  482.     V.z = P1.z - P0.z;
  483.     V.w = ZERO;
  484.  
  485.     return V;
  486. }
  487.  
  488. /*
  489. ** Return the vector s*V.
  490. */
  491. VECTORFX Vscale(s,V)
  492.     FIXED4D    s;
  493.     VECTORFX V;
  494. {
  495.     V.x = FXMUL(V.x,s);
  496.     V.y = FXMUL(V.y,s);
  497.     V.z = FXMUL(V.z,s);
  498.     V.w = ZERO;
  499.  
  500.     return V;
  501. }
  502.  
  503. /*
  504. ** Return the vector V1+V1.
  505. */
  506. VECTORFX Vadd(V1, V2)
  507.     VECTORFX V1, V2;
  508. {
  509.     VECTORFX V;
  510.  
  511.     V.x = V1.x + V2.x;
  512.     V.y = V1.y + V2.y;
  513.     V.z = V1.z + V2.z;
  514.     V.w = ZERO;
  515.  
  516.     return V;
  517. }
  518.  
  519. /*
  520. ** Return the vector V1-V1.
  521. */
  522. VECTORFX Vsub(V1, V2)
  523.     VECTORFX V1, V2;
  524. {
  525.     VECTORFX V;
  526.  
  527.     V.x = V1.x - V2.x;
  528.     V.y = V1.y - V2.y;
  529.     V.z = V1.z - V2.z;
  530.     V.w = ZERO;
  531.  
  532.     return V;
  533. }
  534.  
  535. /*
  536. ** Return the point P+V.
  537. */
  538. POINTFX4D PVadd(P,V)
  539.     POINTFX4D P;
  540.     VECTORFX V;
  541. {
  542.     POINTFX4D p;
  543.  
  544.     p.x = P.x + V.x;
  545.     p.y = P.y + V.y;
  546.     p.z = P.z + V.z;
  547.     p.w = ONE;
  548.  
  549.     return p;
  550. }
  551.  
  552. /*
  553. ** Implementation Module: ray
  554. ** Purpose: ray manipulation.
  555. **
  556. */
  557.  
  558. RAYFX CreateRay(P0,P1)
  559.     POINTFX4D P0,P1;
  560. {
  561.     RAYFX R;
  562.  
  563.     R.P0 = P0;
  564.     R.P1 = P1;
  565.     return R;
  566. }
  567.  
  568. RAYFX RxT4D(R,T)
  569.     RAYFX R;
  570.     MATRIXFX *T;
  571. {
  572.     RAYFX NewRay;
  573.  
  574.     NewRay.P0 = PxT4D(R.P0, T);
  575.     NewRay.P1 = PxT4D(R.P1, T);
  576.  
  577.     return NewRay;
  578. }
  579.  
  580.